/**
 * 
 */
package diary;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JButton;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;

import database.Database;

/**
 * @author Kevin Hanson
 * 
 */
public class DiaryPanel extends JPanel {
	private Connection conn = null;
	private static Statement stat = null;
	private ResultSet rs = null;
	private DefaultListModel headListModel = null;
	private JList diaryHeadList = null;
	private JTextArea textArea = null;

	/**
	 * 
	 */
	public DiaryPanel() {
		try {
			conn = Database.getConnection();
			stat = conn.createStatement();
		} catch (SQLException ex) {
			System.out.print(ex.getMessage());
			ex.printStackTrace();
		}

		createGUI();
		updateDiaryHeadListData();
		updateDiaryContentData();
	}

	public void createGUI() {
		setLayout(new BorderLayout());

		// Diary head list, west pane
		headListModel = new DefaultListModel();
		diaryHeadList = new JList(headListModel);
		diaryHeadList.addMouseListener(new DiaryMouseListener());

		JScrollPane dhlsp = new JScrollPane(diaryHeadList);
		dhlsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		dhlsp.setPreferredSize(new Dimension(140, 60));
		dhlsp.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createTitledBorder("Diary List"), BorderFactory.createEmptyBorder(5, 5, 5, 5)));		

		// Diary content, center pane
		int width = 300, height = 1000;
		textArea = new JTextArea();
		textArea.setDoubleBuffered(true);
		textArea.setLineWrap(true);
		textArea.setFont(new Font(null, Font.BOLD, 16));
		textArea.setTabSize(4);
		textArea.setLineWrap(true);
		textArea.setColumns(100);

		JScrollPane tasp = new JScrollPane(textArea);
		tasp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		tasp.setPreferredSize(new Dimension(width, height));
		tasp.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Diary content"),
				BorderFactory.createEmptyBorder(5, 5, 5, 5)));

		// Action buttons, east pane
		JPanel ap = new JPanel();
		ap.setLayout(new BoxLayout(ap, BoxLayout.Y_AXIS));
		ap.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Action"),
				BorderFactory.createEmptyBorder(5, 5, 5, 5)));

		JButton jb0 = new JButton("Save");
		jb0.setMinimumSize(new Dimension(100, 20));
		jb0.setMaximumSize(new Dimension(100, 20));
		jb0.addActionListener(new DiaryButtonListener());
		JButton jb1 = new JButton("New");
		jb1.setMinimumSize(new Dimension(100, 20));
		jb1.setMaximumSize(new Dimension(100, 20));
		jb1.addActionListener(new DiaryButtonListener());
		JButton jb2 = new JButton("Delete");
		jb2.setMinimumSize(new Dimension(100, 20));
		jb2.setMaximumSize(new Dimension(100, 20));
		jb2.addActionListener(new DiaryButtonListener());

		ap.add(jb0);
		ap.add(jb1);
		ap.add(jb2);

		add(dhlsp, BorderLayout.WEST);
		add(tasp, BorderLayout.CENTER);
		add(ap, BorderLayout.EAST);
	}

	private void updateDiaryContentData() {
		if (diaryHeadList.isSelectionEmpty())
			diaryHeadList.setSelectedIndex(0);
		String head = headListModel.getElementAt(diaryHeadList.getSelectedIndex()).toString();
		System.out.println(head);
		String str = String.format("SELECT content FROM diary WHERE date = '%s';", head);
		try {
			rs = stat.executeQuery(str);
			str = rs.getString("content");
			str = (str == null) ? " " : str;
			textArea.setText(str);
			rs.close();
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
			ex.printStackTrace();
			System.exit(-1);
		}
	}

	private void updateDiaryHeadListData() {
		int lastIndex = diaryHeadList.getSelectedIndex(); // reserve last selection
		headListModel.removeAllElements();
		try {
			rs = stat.executeQuery("SELECT date FROM diary ORDER BY date;");
			while (rs.next()) {
				headListModel.addElement(rs.getString("date"));
			}
			rs.close();
		} catch (SQLException ex) {
			System.out.print(ex.getMessage());
			ex.printStackTrace();
		}

		diaryHeadList.setSelectedIndex(lastIndex);
	}

	/*
	 * diary action buttons listener
	 */
	class DiaryButtonListener implements ActionListener {
		public DiaryButtonListener() {
		}

		@Override
		public void actionPerformed(final ActionEvent e) {
			javax.swing.SwingUtilities.invokeLater(new Runnable() {
				public void run() {
					try {
						if (e.getActionCommand() == "New") {
							stat.execute("INSERT INTO diary VALUES (null, datetime('now'), null);");
							if (!conn.getAutoCommit())
								conn.commit();

							updateDiaryHeadListData();
							updateDiaryContentData();
						} else if (e.getActionCommand() == "Delete") {
							String date = headListModel.getElementAt(diaryHeadList.getSelectedIndex()).toString();
							String str = String.format("DELETE FROM diary WHERE date = '%s';", date);
							stat.execute(str);
							// System.out.println(str);
							if (!conn.getAutoCommit())
								conn.commit();

							updateDiaryHeadListData();
							updateDiaryContentData();
						} else if (e.getActionCommand() == "Save") {
							// substitute ' with '' as SQL syntax required
							String context = textArea.getText().replace("'--".subSequence(0, 1), "''--".subSequence(0, 2));
							String date = headListModel.getElementAt(diaryHeadList.getSelectedIndex()).toString();
							String str = String.format("UPDATE diary SET content = '%s' WHERE date = '%s';", context, date);
//							System.out.println(context);
							stat.execute(str);
							if (!conn.getAutoCommit())
								conn.commit();
						}
					} catch (SQLException ex) {
						System.out.print(ex.getMessage());
						ex.printStackTrace();
					}
				}
			});
		}
	}

	public class DiaryMouseListener extends MouseAdapter {
		/*
		 * Invoke a thread to update diary content
		 * 
		 * @see
		 * java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
		 */
		@Override
		public void mouseClicked(MouseEvent e) {
			int button = e.getButton();
			if (button == MouseEvent.BUTTON1) {
				if (e.getClickCount() == 2 && !diaryHeadList.isSelectionEmpty()) {
					javax.swing.SwingUtilities.invokeLater(new Runnable() {
						public void run() {
							updateDiaryContentData();
						}
					});
				}
			} else if (button == MouseEvent.BUTTON2) {
			} else if (button == MouseEvent.BUTTON3) {
			}
		}
		private JPopupMenu menu = null;

		public DiaryMouseListener() {
			menu = new JPopupMenu("Popup");
			JMenuItem item = new JMenuItem("Open");
			item.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					System.out.println("Menu item Open");
				}
			});
			menu.add(item);

			item = new JMenuItem("New");
			item.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					System.out.println("Menu item New");
				}
			});
			menu.add(item);

			item = new JMenuItem("Delete");
			item.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					System.out.println("Menu item Delete");
				}
			});
			menu.add(item);
		}

		public DiaryMouseListener(JPopupMenu m) {
			menu = m;
		}

		public void mousePressed(MouseEvent ev) {
			if (ev.isPopupTrigger()) {
				menu.show(ev.getComponent(), ev.getX(), ev.getY());
			}
		}

		public void mouseReleased(MouseEvent ev) {
			if (ev.isPopupTrigger()) {
				menu.show(ev.getComponent(), ev.getX(), ev.getY());
			}
		}
	}
}
